﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IMPression.Tests
{
    [TestClass]
    public class ParserTests
    {
        [TestMethod]
        public void ParsingTests()
        {
            EquationParser parser = new EquationParser();

            Assert.AreEqual(4, parser.Calculate("2*2"));
            Assert.AreEqual(-4, parser.Calculate("4*cos(pi)"));
            Assert.IsTrue(double.IsNaN(parser.Calculate("int((fact((φ*2-1)^2)+1/4)*4)")));
            
        }

        [TestMethod]
        public void TrigonometricTests()
        {
            EquationParser parser = new EquationParser();

            Assert.AreEqual(1, parser.Calculate("cos(2pi)"));
            Assert.AreEqual(0, parser.Calculate("rnd(tan(pi); 5)"));
            Assert.AreEqual(-1.248, parser.Calculate("rnd(tan⁻¹(cos(60)*π); 3)"));
        }

        [TestMethod]
        public void GammaTests()
        {
            EquationParser parser = new EquationParser();

            Assert.AreEqual(24, parser.Calculate("gamma(5)"));
            Assert.AreEqual(0.4494617, parser.Calculate("rnd(loggamma(e); 7)"));
        }

        [TestMethod]
        public void VariableTests()
        {
            EquationParser parser = new EquationParser();

            Assert.AreEqual(125, parser.Calculate("int(38x+y(a/t*pi))", "x=3; y=9.1; a=2; t=5"));
        }

        [TestMethod]
        public void PhiTests()
        {
            EquationParser parser = new EquationParser();

            Assert.AreEqual(1, parser.Calculate("phi²-phi"));
            Assert.AreEqual(parser.Calculate("rnd(1/phi; 10)"), parser.Calculate("rnd(phi^2-2; 10)"));
        }

        [TestMethod]
        public void FunctionTests()
        {
            EquationParser p = new EquationParser();

            Assert.AreEqual(5, p.Calculate("abs(5)"));
            Assert.AreEqual(5, p.Calculate("abs(-5)"));

            Assert.AreEqual(120, p.Calculate("fact(5)"));
            Assert.AreEqual(1, p.Calculate("fact(0)"));

            Assert.AreEqual(15, Math.Truncate(p.Calculate("fact2(5)")));
            Assert.AreEqual(1.38, Math.Round(p.Calculate("fact2(1.5)"), 2));

            Assert.AreEqual(0, p.Calculate("rnd(sin(pi); 15)"));
            Assert.AreEqual(-1, p.Calculate("cos(pi)"));
            Assert.AreEqual(0, p.Calculate("rnd(tan(pi); 15)"));
        }
    }
}
